package com.talkweb.securitycamera.data.hadoopDB;

import com.talkweb.securitycamera.data.bean.FileNodeEntity;
import ohos.app.Context;
import ohos.data.distributed.common.*;
import ohos.data.distributed.user.SingleKvStore;

import java.util.ArrayList;

/**
 * @version 1.0.1
 * @description: 分布式数据库 基类
 * @program: security-camera
 * @Author xiaozhijun
 * @Date 2021/1/29 8:39
 */
public abstract class BaseHadoopDb implements IHadoopDb<SingleKvStore> {
    /**
     * 分布式数据库对象
     */
    private SingleKvStore singleKvStore;

    /**
     * 分布式数据库管理对象
     */
    private KvManager kvManager;

    /**
     * 分布式数据库id--唯一标识
     */
    private String storeId;

    @Override
    public SingleKvStore initOrGetDB(Context context, String storeId) {
        KvManagerConfig kvManagerConfig = new KvManagerConfig(context);
        kvManager = KvManagerFactory.getInstance().createKvManager(kvManagerConfig);
        Options options = new Options();
        options.setCreateIfMissing(true)
                .setEncrypt(false)
                .setKvStoreType(getMvStoreType())
                .setSchema(getHadoopSchema());
        this.storeId = storeId;
        singleKvStore = kvManager.getKvStore(options, storeId);
        return singleKvStore;
    }

    @Override
    public void close() {
        if (singleKvStore != null && kvManager != null) {
            kvManager.closeKvStore(singleKvStore);
        }
    }

    @Override
    public void delete() {
        if (singleKvStore != null && kvManager != null) {
            kvManager.deleteKvStore(storeId);
        }
    }

    /**
     * 获取分布式数据库Schema
     * @return
     */
    private Schema getHadoopSchema() {
        //把上面的字段，封装到Schema对象
        Schema schema = new Schema();
        String[] indexStrs = getDbIndexs();
        if (indexStrs != null) {
            int indexLength = indexStrs.length;
            ArrayList<String> indexList = new ArrayList<>();
            for (int i = 0; i < indexLength; i++) {
                //schema默认有一个rootFieldNode
                indexList.add("$." + indexStrs[i]);
                schema.setIndexes(indexList);
            }
        }

        ArrayList<FileNodeEntity> allColume = getDbColumeInfo();
        if (allColume != null) {
            allColume.forEach((item) -> {
                schema.getRootFieldNode().appendChild(getFileNode(item));
            });

        }
        schema.setSchemaMode(getSchemaMode());
        return schema;
    }

    /**
     * 获取分布式数据库所有关键字
     * @return
     */
    protected abstract ArrayList<FileNodeEntity> getDbColumeInfo();

    /**
     * 获取分布式数据库索引字段
     * @return
     */
    protected abstract String[] getDbIndexs();

    /**
     * 获取节点
     * @param entity
     * @return
     */
    private FieldNode getFileNode(FileNodeEntity entity) {
        FieldNode nodes = new FieldNode(entity.getFieldName());
        nodes.setType(entity.getType());
        if (!entity.isNullable()) {
            nodes.setNullable(entity.isNullable());
        }
        return nodes;
    }

    /**
     * 获取Schema模式,默认精确模式
     * @return
     */
    protected SchemaMode getSchemaMode() {
        return SchemaMode.STRICT;
    }

    /**
     * 获取数据库的类型 默认单版本
     * @return
     */
    protected KvStoreType getMvStoreType() {
        return KvStoreType.SINGLE_VERSION;
    }

    /**
     * 获取数据库对象
     * @return
     */
    protected SingleKvStore getKvStore() {
        return singleKvStore;
    }

}
